home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-22 | 52.4 KB | 1,880 lines | [TEXT/MPS ] |
- /*
- File: ODPrcs.cpp
-
- Contains: OpenDoc Process runtime functions
-
- Owned by: Nick Pilch
-
- Copyright: © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <7> .03.1996 NP Added comment about lack of error handling
- in one routine.
- <6> 3/4/96 TJ Removed WASSERT.
- <5> 3/1/96 JP 1314798: Made new documents run from temp
- file
- <4> 2/6/96 eeh 1318481: change 0 to smCurrentScript
- <3> 1/15/96 TJ Cleaned Up
- <2> 1/15/96 JA 1269485: Made GetPrefsFileSpec nonstatic.
- 1303072: Changed criteria for which logo to
- show in splash screen.
- <52> 10/31/95 TJ Made the Splash Screen Non-Modal.#1297413
- <51> 10/26/95 TÇ 1296574 GM:Cannot set default memory
- partition size.
- <50> 10/25/95 TÇ 1281409 GM: OpenDoc needs an AboutBox.
- <49> 10/12/95 eeh 1287143: check for open resource forks
- <48> 9/29/95 eeh 1287262: use ShellDef.h
- <47> 9/27/95 TÇ 1287770 GM:Crash when an application is
- dragged over the launcher
- <46> 9/27/95 eeh 1284464: use ClipStringToBytes
- <45> 9/8/95 eeh 1268998: get prefs file name from resource
- <44> 9/8/95 CG #1282518 FB1:Shell moves "bad" aliases from
- OD Libs fldr if found.
- <43> 9/8/95 TÇ 1271995 FB1:Get error -35 or -44 opening
- stationery off write-protected volume
- <42> 9/5/95 TÇ 1281030 FB1:OpenDoc(tm) corrupts ODF Shared
- libraries
- <41> 8/29/95 jpa Rename Toolbox calls for Univ Hdrs 2.1.
- [1279173]
- <40> 8/26/95 TÇ 1269688 FB1: There is an unnecessary
- variable
- <39> 8/22/95 eeh 1278280: include RlShlDef.h
- <38> 8/22/95 eeh 1276821:
- kOpenDocShellSignature->kODShellSignature
- <37> 8/16/95 CG #1274825: Fixed creating stationery for
- libs containing multiple editors.
- <36> 8/3/95 TÇ Remove dependency on obsolete SysPrDef.h
- <35> 6/30/95 TÇ 1251872 BB: Can't open stationery if file
- name becomes too long. 1264094 BB:Custom
- document size cannot be attached to a
- stationery.
- <34> 6/25/95 TÇ 1242642 BB: Turn on ODDebug warning if
- refcount is wrong in
- ODRefCntObjectsomUninit.
- <33> 6/2/95 TÇ Need to copy resources into newly created
- documents. Completes fix to 4
- BB:1233106,1242232, 1254312, 1242283
- <32> 5/25/95 jpa Removed CODE 7 -- CFM68K b1 doesn't
- generate one. [1241078]
- <31> 5/19/95 TÇ 1155852 BB: String constants need to be
- moved to resource for Localization, 1235942
- Launching the OpenDoc pref file causes a
- 1000 exception to be thrown, 1249396 (was
- BB) OpenDoc shell should serialize
- stationery creation.
- <30> 5/10/95 CG #1243610 BB: Shell should not rely on the
- constant kNMAPid.
- <29> 5/7/95 TÇ 1155852 BB: String constants need to be
- moved to resource for Localization (mostly
- done)
- <28> 4/29/95 TÇ 1216130 BB: Shell should open top draft
- upon receipt of open document Apple event
- <27> 4/24/95 eeh 1216915: remove unnecessary param
- <26> 4/24/95 eeh 1240662: send keyODActivateEventCause param
- in activate event
- <25> 4/15/95 TÇ #1216915 DR/BB:Trying to open a document
- that is already open causes an error.
- <24> 4/14/95 TÇ #1186294 DR/BB: Binding for editor also
- affect making stationary.
- <23> 4/7/95 eeh 1221297: eventID param to
- VerifyAndLaunchDocumentStub
- <22> 3/31/95 TÇ 1223465 BB: Opening and creating documents
- under low disk space. (Creating documents
- under low disk space part fixed).
- 1211032 BB: Invalid Permissions error
- opening locked document
- <21> 3/28/95 TÇ #1151710 BB: Toolbox running out of app
- heap. Document Size dialog implemented.
- TestAndVerify now uses SIZE -1 resource in
- OpenDoc Preferences if it exists.
- <20> 3/24/95 CG #1226064: ODTestmain can create stationary.
- <19> 2/24/95 EL 1220392: fix access check bug in last
- checkin.
- <18> 2/23/95 EL 1220392: checking read only fails on file
- share volumes.
- <17> 2/20/95 TÇ #1210979 BB: 5-$ Bugs need to be evaluated
- and removed from Shell
- #1221861 BB: Incomplete AOCE support needs
- to be removed from OpenDoc
- <16> 2/13/95 TÇ 1193359: BB: Opening stationery on other
- volume causes bus error in Messaging code
- 1211032: BB: Invalid Permissions Error
- opening locked document
- <15> 2/2/95 CG #1205177: "Editors" and "OpenDoc
- Libraries" folders are being registered
- with cfm (PPC only).
- <14> 1/12/95 jpa Removed HandToHand workaround for bug in
- Dagon a1 [1210936]
- <13> 1/6/95 jpa Added new docstub rsrcs to tables [1196515]
- <12> 12/5/94 jpa Added GetLaunchFailedParams. [1198075,
- 1158966]
- <11> 10/24/94 jpa Took out WASSERTM call & Use BlockMove, not
- BlockMoveData [68k].
- <10> 10/12/94 TÇ 68K: use local static version of HandToHand
- <9> 10/10/94 TÇ #1191470 Need both 68K and PPC document
- stub application
- <8> 10/7/94 TÇ #1191470 Need both 68K and PPC document
- stub application
- <7> 9/29/94 RA 1189812: Mods for 68K build.
- <6> 9/8/94 eeh #1185443: forgot to eliminate strcat and
- strcpy.
- <5> 9/8/94 eeh #1185443. Lotso changes to separate
- document with content from what gets
- launched.
- <4> 8/29/94 TÇ #1158280 OpenDoc™ should not overwrite old
- stationery files when creating new ones
- <3> 8/25/94 TÇ #1183223 Enabled launching of documents in
- folders other than that of the OpenDoc
- libraries. Added new call:
- VerifyAndLaunchDocument
- <2> 8/22/94 TÇ #1182448 System Process quits when no
- OpenDoc documents are running
- <1> 8/22/94 TÇ first checked in
-
- To Do:
- Change all uses of ODFileSpec and FSSpecPtr to PlatformFile objects
- In Progress:
-
- */
-
- #ifndef _EXCEPT_
- #include <Except.h>
- #endif
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
- #ifndef _ODPRCS_
- #include "ODPrcs.h"
- #endif
-
- #ifndef _SHELLDEF_
- #include "ShellDef.h"
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdDefs_defined
- #include <StdDefs.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_ODRegistry_defined
- #include "ODRgstry.xh"
- #endif
-
- #ifndef _PLFMFILE_
- #include "PlfmFile.h"
- #endif
-
- #ifndef _PASCLSTR_
- #include "PasclStr.h"
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
-
- #ifndef __OSEVENTS__
- #include <OSEvents.h>
- #endif
-
- #ifndef __ALIASES__
- #include <Aliases.h>
- #endif
-
- #ifndef __FILES__
- #include <Files.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef __EVENTS__
- #include <Events.h>
- #endif
-
- #ifndef __APPLEEVENTS__
- #include <AppleEvents.h>
- #endif
-
- #ifndef __PROCESSES__
- #include <Processes.h>
- #endif
-
- #ifndef __STRING__
- #include <String.h>
- #endif
-
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
-
- #ifndef __SCRIPT__
- #include <script.h>
- #endif
-
- #ifndef __FINDER__
- #include <Finder.h>
- #endif
-
- #ifndef _ODMEMORY_
- #include <ODMemory.h>
- #endif
-
- #ifndef _REGISTER_
- #include <RegisterFileLibs.h>
- #endif
-
- //==============================================================================
- // Constants
- //==============================================================================
-
- #define kMaxFileNameLen 31
-
- #define kNumDocStubRsrcs 11 /* was 12 before CFM68K a3 */
-
- const ODULong docStubRsrcType[kNumDocStubRsrcs] =
- { kDocStubRsrcType,
- kDocStubRsrcType,
- kDocStubRsrcType,
- kDocStubRsrcType,
- kDocStubRsrcType,
- kDocStubRsrcType,
- kDocStubRsrcType,
- kDocStubRsrcType,
- // kDocStubRsrcType,
- kDocStubRsrcType,
- kDocStubRsrcType,
- kSIZERsrcType
- };
-
- const ODULong docStubRsrcID[kNumDocStubRsrcs] =
- { kDocStubRsrcID0,
- kDocStubRsrcID1,
- kDocStubRsrcID2,
- kDocStubRsrcID3,
- kDocStubRsrcID4,
- kDocStubRsrcID5,
- kDocStubRsrcID6,
- kDocStubRsrcID7,
- kDocStubRsrcID8,
- kDocStubRsrcID9,
- // kDocStubRsrcID10,
- kDocStubSIZEID
- };
-
- const ODULong copiedRsrcType[kNumDocStubRsrcs] =
- { kcfrgRsrcType,
- kMainCFMType,
- kscszRsrcType,
- kMainCFMType,
- kMainCFMType,
- kCODERsrcType,
- kCODERsrcType,
- kCODERsrcType,
- // kCODERsrcType,
- kMainCFMType,
- kMainCFMType,
- kSIZERsrcType
- };
-
- const ODULong copiedRsrcID[kNumDocStubRsrcs] =
- { kcfrgID,
- kMainCFMPPCID,
- kscszID,
- kMainCFM68KID,
- kMainCFM68KID1,
- kCODEID0,
- kCODEID1,
- kCODEID6,
- // kCODEID7,
- kSOMMemCFM68KID,
- kSOMMemCFMPPCID,
- kSIZEID
- };
-
-
- enum
- {
- kIsNotSameAsStub = 0,
- kIsSameAsStub = 1,
- kIsAlreadyLaunched = 2
- };
- typedef ODSShort DocStubType;
-
- struct ITextData {
- ScriptCode theScriptCode;
- LangCode theLangCode;
- Str255 theText;
- };
- typedef struct ITextData ITextData;
-
- struct EditorUserStringList {
- Str255 editor;
- ITextData name;
- EditorUserStringList* next;
- };
- typedef struct EditorUserStringList EditorUserStringList;
-
- //==============================================================================
- // Macros
- //==============================================================================
-
- #define CHECK(EXPR) if ((err=(EXPR)) == noErr) ; else return err
- #define CHECKR(EXPR,RET) if ((err=(EXPR)) == noErr) ; else return (RET)
-
- //==============================================================================
- // Function Prototype
- //==============================================================================
-
- static ODBoolean IsAProcessRunning(OSType procType, OSType procSignature);
-
- static void CreateTempName(short seed, Str255 name, ODBoolean isFile);
- static OSErr CreateUniqueTmpFolderForFile(ODFileSpec* result,
- Str63 fileName);
- static OSErr MakeDocumentStub(AEDesc *document, FSSpec* documentStub,
- FSSpec* documentSpec,
- DocStubType* isDuplicate, DescType eventID, ODBoolean unsavedDoc);
-
- // Document Launching
- static OSErr TestAndUpdate(Handle origRsrc,ResType rtype,short rid);
- static OSErr CreateStationerySeed(FSSpecPtr theDocument, FSSpec* seedFSSPtr);
- static size_t ODXstrlen(const char *s);
- static char* ODXstrncpy(char* destStr, char* srcStr, size_t n);
- static char* ODXstrncat(char* destStr, char* srcStr, size_t n);
- static char ODXmemcmp(char* buffer1,char* buffer2,unsigned int len);
- ODBoolean myEqualPascalStrings(ConstStr255Param str1, ConstStr255Param str2);
- static ODSLong GetFldrDirID(ODFileSpec theFolderSpec);
- ODFileSpec FindODBinary(ODSShort fldrVRefNum,
- ODSLong fldrDirID, Str255 pbinaryName);
- OSErr GetEditorUserStringPairs(ODSShort resRefNum, EditorUserStringList** pairs, ODUShort* editorCount);
- OSErr GetEditorSetFromNMAP( ODHandle nmap, EditorUserStringList** pairs, ODUShort* editorCount );
- static void MoveToTrash( short vRefnum, long dirID, Str255 name );
-
-
- //==============================================================================
- // GetOpenDocBinaryFileSpec
- //==============================================================================
-
- ODFileSpec GetOpenDocBinaryFileSpec(char* binaryName)
- {
-
- ODFileSpec filespec;
- Str255 pbinaryName;
- ODUShort pbinaryLen = 0;
-
- if (binaryName)
- {
- pbinaryLen = ODXstrlen(binaryName);
-
- if (pbinaryLen>255)
- {
- pbinaryLen = 255;
- }
-
- ODXstrncpy((char*)&(pbinaryName[1]),binaryName,pbinaryLen);
- }
-
- ClipStringToBytes( pbinaryName, pbinaryLen, smCurrentScript );
-
- ODFileSpec odLibsFldrSpec = GetOpenDocLibsFldrSpec();
- ODSLong dirID = GetFldrDirID(odLibsFldrSpec);
- filespec = FindODBinary(odLibsFldrSpec.vRefNum, dirID, pbinaryName);
-
- return filespec;
- }
-
- //==============================================================================
- // FindODBinary
- //==============================================================================
-
- ODFileSpec FindODBinary(ODSShort fldrVRefNum,
- ODSLong fldrDirID, Str255 pbinaryName)
- {
- CInfoPBRec CinfoPB;
- Str255 fileName;
- ODFileSpec fileSpec;
- FSMakeFSSpec( fldrVRefNum,
- fldrDirID,
- pbinaryName, &fileSpec);
-
- //check that this is not a bogus folder
- if (fldrDirID != -1)
- {
- memset (&CinfoPB,0,sizeof(CinfoPB));
- CinfoPB.dirInfo.ioNamePtr = (StringPtr)&fileName;
- CinfoPB.dirInfo.ioFDirIndex = 1;
- CinfoPB.dirInfo.ioVRefNum = fldrVRefNum;
- CinfoPB.dirInfo.ioDrDirID = fldrDirID;
-
- // Loop through all the files in Library folder
- for(ODSShort i = PBGetCatInfoSync(&CinfoPB);
- i == noErr;
- i = PBGetCatInfoSync(&CinfoPB))
- {
- // if this is a folder
- if ((CinfoPB.dirInfo.ioFlAttrib & (1<<4)))
- {
- FSSpec fldrSpec;
- FSMakeFSSpec(CinfoPB.hFileInfo.ioVRefNum,
- CinfoPB.hFileInfo.ioFlParID,
- fileName, &fldrSpec);
- OSErr err = RegisterFileLibs(&fldrSpec);
- fileSpec = FindODBinary(fldrVRefNum,
- CinfoPB.dirInfo.ioDrDirID,
- pbinaryName);
- }
- else
- {
- // if this is an alias, resolve and do the right thing
- if ((CinfoPB.hFileInfo.ioFlFndrInfo.fdFlags & 0x8000) /* kIsAlias */)
- {
- FSSpec aliasSpec;
- Boolean targetIsFolder = kODFalse;
- Boolean wasAliased = kODFalse;
-
- ODError result = FSMakeFSSpec(CinfoPB.hFileInfo.ioVRefNum,
- CinfoPB.hFileInfo.ioFlParID,
- fileName, &aliasSpec);
- if (result == noErr)
- {
- //resolve alias
- result = ResolveAliasFile(&aliasSpec, kODTrue,
- &targetIsFolder, &wasAliased);
- if (result == noErr)
- {
- if (aliasSpec.vRefNum != fldrVRefNum)
- MoveToTrash( CinfoPB.hFileInfo.ioVRefNum,
- CinfoPB.hFileInfo.ioFlParID, fileName );
- else
- {
- if (targetIsFolder)
- {
- OSErr err = RegisterFileLibs(&aliasSpec);
- ODSLong dirID = GetFldrDirID(aliasSpec);
- FindODBinary(aliasSpec.vRefNum,
- dirID, pbinaryName);
- }
- else
- {
- // if this file's name == pbinaryName, make an FSSpec and return it
- if (myEqualPascalStrings(pbinaryName,
- fileName))
- FSMakeFSSpec(aliasSpec.vRefNum,
- aliasSpec.parID, fileName,
- &fileSpec);
- }
- }
- }
- }
- }
- else
- {
- // if this file's name == pbinaryName, make an FSSpec and return it
- if (myEqualPascalStrings(pbinaryName, fileName))
- {
- FSMakeFSSpec(CinfoPB.hFileInfo.ioVRefNum,
- CinfoPB.hFileInfo.ioFlParID,
- fileName, &fileSpec);
- }
- }
- }
-
- CinfoPB.hFileInfo.ioFDirIndex++;
- //need to do this each time since PBGetCatInfo call returns val here
- CinfoPB.hFileInfo.ioNamePtr = (StringPtr)&fileName;
- CinfoPB.hFileInfo.ioVRefNum = fldrVRefNum;
- CinfoPB.hFileInfo.ioDirID = fldrDirID;
- }
- }
- return fileSpec;
- }
-
- //==============================================================================
- // GetOpenDocLibsFldrSpec
- //==============================================================================
-
- ODFileSpec GetOpenDocLibsFldrSpec()
- {
- ODSLong odDirID, libsFldrDirID;
- ODSShort odVRef, libsFldrVRefNum;
- ODFileSpec odFldrSpec;
- Str255 folderName;
-
- GetIndString(folderName, kODXLibsFldrStrID, kODXLibsFldrStrIndex);
- #if ODDebug
- if (folderName[0] == 0)
- DebugStr("\pResource Error: OpenDoc Libraries string not found!");
- #endif
-
- ODError result = FindFolder(kOnSystemDisk, kExtensionFolderType,
- kDontCreateFolder, &libsFldrVRefNum,
- &libsFldrDirID);
- if (result == noErr)
- {
- CInfoPBRec CinfoPB;
- memset (&CinfoPB,0,sizeof(CinfoPB));
- CinfoPB.dirInfo.ioNamePtr = (StringPtr)&folderName;
- CinfoPB.dirInfo.ioFDirIndex = 0;
- CinfoPB.dirInfo.ioVRefNum = libsFldrVRefNum;
- CinfoPB.dirInfo.ioDrDirID = libsFldrDirID;
-
- ODSShort result = PBGetCatInfoSync(&CinfoPB);
- if (result == noErr)
- {
- odVRef = CinfoPB.dirInfo.ioVRefNum;
- odDirID = CinfoPB.dirInfo.ioDrParID;
- result = FSMakeFSSpec(odVRef, odDirID, folderName, &odFldrSpec);
- }
- }
-
- return odFldrSpec;
- }
-
- //------------------------------------------------------------------------------
- // GetFldrDirID
- //------------------------------------------------------------------------------
- static ODSLong
- GetFldrDirID(ODFileSpec theFolderSpec)
- {
- ODSLong dirID=-1;
- CInfoPBRec theParamBlock;
- memset (&theParamBlock,0,sizeof(theParamBlock));
- theParamBlock.dirInfo.ioFDirIndex = 0;
- theParamBlock.dirInfo.ioNamePtr = theFolderSpec.name;
- theParamBlock.dirInfo.ioVRefNum = (ODSShort)theFolderSpec.vRefNum;
- theParamBlock.dirInfo.ioDrDirID = (ODSLong)theFolderSpec.parID;
- ODError result = PBGetCatInfoSync((CInfoPBPtr)&theParamBlock);
- if (result == noErr && (theParamBlock.hFileInfo.ioFlAttrib & (1<<4)))
- dirID = theParamBlock.dirInfo.ioDrDirID;
-
- return dirID;
- }
-
- #ifdef NEEDSYSTEMPROCESS
- #define kODSysProcessType 0x4150504C // 'APPL' ?should be 'appe' eventually
- #define kODSysProcessSignature 0x6F647370 // 'odsp'
-
- //==============================================================================
- // IsODSysProcessRunning
- //==============================================================================
-
- ODBoolean IsODSysProcessRunning()
- {
- return IsAProcessRunning(kODSysProcessType,kODSysProcessSignature);
-
- ProcessSerialNumber psn = {0,kNoProcess};
- ProcessInfoRec aProcess;
- aProcess.processInfoLength = sizeof(ProcessInfoRec);
- aProcess.processName = NULL;
- aProcess.processAppSpec = NULL;
-
- while (GetNextProcess(&psn) == noErr)
- if (GetProcessInformation(&psn,&aProcess) == noErr)
- if (aProcess.processType == kODSysProcessType &&
- aProcess.processSignature == kODSysProcessSignature)
- return true;
- return false;
- }
- #endif
-
- //==============================================================================
- // AreODDocumentsRunning
- //==============================================================================
-
- ODBoolean AreODDocumentsRunning()
- {
- ProcessSerialNumber psn = {0,kNoProcess};
- ProcessInfoRec aProcess;
- aProcess.processInfoLength = sizeof(ProcessInfoRec);
- aProcess.processName = NULL;
- aProcess.processAppSpec = NULL;
-
- while (GetNextProcess(&psn) == noErr)
- if (GetProcessInformation(&psn,&aProcess) == noErr)
- if (aProcess.processType != 'APPL' &&
- aProcess.processSignature == kODShellSignature)
- return true;
- return false;
- }
-
- //==============================================================================
- // FileIsReadOnly
- //==============================================================================
-
- OSErr FileIsReadOnly(ODFileSpec* fs, ODBoolean* result)
- {
- // Note: copied from PlatformFile::IsLocked. OpenDoc™ DOES NOT link in Util.lib. -TÇ
-
- CInfoPBRec pbBlock;
- *result = kODFalse;
- OSErr err = noErr;
-
- // Check to see whether the volume is locked
-
- // Eric's original code with slight modifications.
- // Appears to be needed in the case of a locked floppy. -TÇ
- HParamBlockRec pb;
- pb.volumeParam.ioCompletion = kODNULL;
- pb.volumeParam.ioNamePtr = kODNULL;
- pb.volumeParam.ioVRefNum = fs->vRefNum;
- pb.volumeParam.ioVolIndex = 0;
-
- err = PBHGetVInfoSync(&pb);
- if (err) return err;
-
- *result = (pb.volumeParam.ioVAtrb & 0x80) ? kODTrue : kODFalse;
-
- // Check to see whether the directory is locked
- if (*result == kODFalse) {
- // first assume it is a file share volume
- HParamBlockRec paramBlk;
- paramBlk.accessParam.ioCompletion = kODNULL;
- paramBlk.accessParam.ioNamePtr = kODNULL;
- paramBlk.accessParam.ioVRefNum = fs->vRefNum;
- paramBlk.accessParam.ioDirID = fs->parID;
- paramBlk.accessParam.ioACAccess = 0;
- err = PBHGetDirAccessSync(¶mBlk);
-
- if (err == noErr) { /* it is a file share volume, look at the access right */
- if ((paramBlk.accessParam.ioACAccess & 0x04000000) == 0) /* no write access */
- *result = kODTrue;
- }
- else if (err == paramErr) { /* it is not file share, look at directory */
- pbBlock.dirInfo.ioCompletion = kODNULL;
- pbBlock.dirInfo.ioNamePtr = kODNULL;
- pbBlock.dirInfo.ioVRefNum = fs->vRefNum;
- pbBlock.dirInfo.ioFDirIndex = -1;
- pbBlock.dirInfo.ioDrDirID = fs->parID;
- pbBlock.dirInfo.ioFlAttrib = 0;
- err = PBGetCatInfoSync(&pbBlock);
- if (err) return err;
- if (pbBlock.dirInfo.ioFlAttrib & 1)
- *result = kODTrue;
- }
- else
- return err;
- }
-
- // Check to see whether the file is locked
- if (*result == kODFalse) {
- pbBlock.hFileInfo.ioCompletion = kODNULL;
- pbBlock.hFileInfo.ioFDirIndex = 0;
- pbBlock.hFileInfo.ioNamePtr = fs->name;
- pbBlock.hFileInfo.ioVRefNum = fs->vRefNum;
- pbBlock.hFileInfo.ioDirID = fs->parID;
-
- err = PBGetCatInfoSync(&pbBlock);
- if (err) return err;
-
- if (pbBlock.hFileInfo.ioFlAttrib & 1)
- *result = kODTrue;
- }
-
- return noErr;
- }
-
- //==============================================================================
- // GetVolumeWritableSpace
- //==============================================================================
-
- ODULong GetVolumeWritableSpace(ODFileSpec* fs, ODULong* error)
- {
- ODULong err = noErr;
- HParamBlockRec paramBlk;
- ODBoolean writable = kODFalse;
-
- if (error == kODNULL)
- error = &err;
-
- paramBlk.accessParam.ioCompletion = kODNULL;
- paramBlk.accessParam.ioNamePtr = kODNULL;
- paramBlk.accessParam.ioVRefNum = fs->vRefNum;
- paramBlk.accessParam.ioDirID = fs->parID;
- paramBlk.accessParam.ioACAccess = 0;
- *error = PBHGetDirAccessSync(¶mBlk);
-
- if (*error == noErr) { /* it is a file share volume, look at the access right */
- if (paramBlk.accessParam.ioACAccess & 0x04000000)
- writable = kODTrue;
- }
- else if (*error == paramErr) { /* it is not file share, look at directory */
- CInfoPBRec pbBlock;
- pbBlock.dirInfo.ioCompletion = kODNULL;
- pbBlock.dirInfo.ioNamePtr = kODNULL;
- pbBlock.dirInfo.ioVRefNum = fs->vRefNum;
- pbBlock.dirInfo.ioFDirIndex = -1;
- pbBlock.dirInfo.ioDrDirID = fs->parID;
- pbBlock.dirInfo.ioFlAttrib = 0;
- *error = PBGetCatInfoSync(&pbBlock);
- if (*error) return 0;
-
- if (!(pbBlock.dirInfo.ioFlAttrib & 1))
- writable = kODTrue;
- }
- else
- return 0;
-
- if (writable != kODFalse) {
- // how much space on this writable volume?
- HParamBlockRec hpb;
- hpb.volumeParam.ioVolIndex = 0;
- hpb.volumeParam.ioNamePtr = kODNULL;
- hpb.volumeParam.ioVRefNum = fs->vRefNum;
-
- *error = PBHGetVInfoSync(&hpb);
- if (*error) return 0;
-
- if (!(hpb.volumeParam.ioVAtrb & 0x80))
- return ((hpb.volumeParam.ioVFrBlk * hpb.volumeParam.ioVAlBlkSiz) / 1024);
- // Appears to be needed in the case of a locked floppy. -TÇ
- }
-
- *error = kODErrDirectoryNotHaveWriteAccess;
- return 0;
- }
-
- //==============================================================================
- // GetDescFSSpec
- //==============================================================================
-
- OSErr
- GetDescFSSpec(AEDesc *desc, FSSpec &spec)
- {
- AEDesc resultDesc;
- OSErr err = AECoerceDesc(desc, typeFSS, &resultDesc);
- if (err) return err;
- spec = **(FSSpec**)(resultDesc.dataHandle);
- AEDisposeDesc(&resultDesc);
- return noErr;
- }
-
-
- //==============================================================================
- // MakeDocumentStub
- //==============================================================================
-
- static void CreateTempName(short seed, Str255 name, ODBoolean isFile)
- {
- // Don't modify this one!
- char* nmSeed = isFile? "ODShellTempFile" : "ODShellTempFolder";
- ODXstrncpy((char*)name, nmSeed, ODXstrlen(nmSeed)+1);
-
- char theNum[10];
- NumToString(seed, (StringPtr)theNum);
- // WASSERT(theNum[0] <= 5);
- p2cstr((StringPtr)theNum);
-
- ODXstrncat((char*)name, theNum, ODXstrlen(theNum)+1);
- c2pstr((char *)name);
- }
-
- OSErr CreateUniqueTmpFolderForFile(ODFileSpec* result,
- Str63 fileName)
- {
- Str255 myName;
- ODSLong myDirID;
- ODSShort myVRef;
-
- FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder, &myVRef, &myDirID);
-
- OSErr err;
- short limit = 100;
- short seed = 1;
- while (--limit)
- {
- CreateTempName(seed++, myName, kODFalse);
- long createdDirID;
- err = DirCreate(myVRef, myDirID, myName,
- &createdDirID);
- if (err == noErr)
- {
- FSMakeFSSpec(myVRef, createdDirID, fileName, result);
- return noErr;
- }
- }
- return err;
- }
-
- static OSErr MakeDocumentStub(AEDesc *document, FSSpec* documentStub,
- FSSpec* documentSpec,
- DocStubType* isDuplicate,
- DescType eventID,
- ODBoolean unsavedDoc)
- {
- OSErr err;
-
- FSSpec documentFSSpec;
- CHECK(GetDescFSSpec(document, documentFSSpec));
- *documentSpec = documentFSSpec;
-
- if (WasLaunchedThenActivate(documentSpec, eventID, err ))
- {
- *isDuplicate = kIsAlreadyLaunched;
- return err;
- }
-
- FInfo documentFInfo;
- err= FSpGetFInfo(&documentFSSpec, &documentFInfo);
- if (err) return err;
-
- // if it's a read-only file OR if it's on a server OR if it's stationery,
- // OR it's unsaved (i.e. a New document)
- // make a new one.
-
- ODBoolean makeNewOne;
- err = FileIsReadOnly(&documentFSSpec, &makeNewOne);
- if (err) return err;
- makeNewOne = makeNewOne || (((documentFInfo.fdFlags)&kIsStationary)!=0) ||
- (documentFInfo.fdCreator != kODShellSignature) || unsavedDoc;
- if (!makeNewOne ||
- documentFInfo.fdType == kEditorFileType)
- {
- *documentStub = documentFSSpec;
- *isDuplicate = kIsSameAsStub;
- return noErr;
- }
-
- // if we get here we need a new file....
- *isDuplicate = kIsNotSameAsStub;
-
- FSSpec newFileSpec;
- err = CreateUniqueTmpFolderForFile(&newFileSpec, documentFSSpec.name);
- if (err) return err;
-
- err = FSpCreate( &newFileSpec, kODShellSignature, documentFInfo.fdType,
- smSystemScript );
- FSpCreateResFile( &newFileSpec, kODShellSignature, documentFInfo.fdType,
- smSystemScript );
- if (!err)
- *documentStub = newFileSpec;
-
- // Need to copy over custom SIZE 0 & 1 resource for proper custom heapsize behaviour
- // for readonly documents and documents newly created from stationery.
-
- short theCurResFile = CurResFile();
- short docResFile = FSpOpenResFile((const FSSpec *)&documentFSSpec,fsRdPerm);
-
- if (docResFile != -1)
- {
- ODHandle size0 = kODNULL;
- size0 = Get1Resource(kSIZERsrcType, 0);
- if (size0)
- DetachResource(size0);
- ODHandle size1 = kODNULL;
- size1 = Get1Resource(kSIZERsrcType, 1);
- if (size1)
- DetachResource(size1);
- CloseResFile( docResFile );
-
- short stubResFile = FSpOpenResFile((const FSSpec *)&newFileSpec,fsRdWrPerm);
- if (size0)
- err = TestAndUpdate(size0,kSIZERsrcType,0);
- if (!err && size1)
- err = TestAndUpdate(size1,kSIZERsrcType,1);
- CloseResFile( stubResFile );
-
- if (size0)
- DisposeHandle(size0);
- if (size1)
- DisposeHandle(size1);
-
- UseResFile(theCurResFile);
- }
-
- return err;
- }
-
- //==============================================================================
- // WasLaunchedThenActivate
- //==============================================================================
-
-
- ODBoolean WasLaunchedThenActivate(
- FSSpec* fileSpec,
- DescType eventID,
- OSErr & err)
- {
- // check if the file we want to open is already open by someone on this machine
- ODULong refNumCount = 0;
- RefNumPtr refNums = kODNULL;
-
- CHECKR(GetLocalPaths(fileSpec, kDataFork, &refNumCount, &refNums), kODFalse);
- DisposePtr((Ptr) refNums);
- refNums = kODNULL;
- ODBoolean refnumForResFork = refNumCount == 0; // don't count on
- // refnumForResFork in the
- // case where
- // we're returning false
- if ( refnumForResFork ) // try again with the resource fork
- {
- CHECKR(GetLocalPaths(fileSpec, kResourceFork, &refNumCount, &refNums),
- kODFalse);
- DisposePtr((Ptr) refNums);
- if (refNumCount == 0)
- return kODFalse;
- }
-
- AppleEvent activateEvent, reply;
- AEDesc addressDesc = {typeNull, kODNULL};
- ProcessSerialNumber psn = {0,kNoProcess};
- ProcessInfoRec aProcess;
-
- // DisposePtr((Ptr) refNums); // <eeh> why doesn't this come before the return above?
- // create the activate event
- CHECKR(AECreateAppleEvent(kAEOpenDocSuite, kODActivateEvent, &addressDesc,
- kAutoGenerateReturnID, kAnyTransactionID, &activateEvent)
- , kODTrue);
-
- err = AEPutParamPtr(&activateEvent, keyDirectObject, typeFSS,
- (Ptr) fileSpec, sizeof(*fileSpec));
- if (err != noErr)
- {
- AEDisposeDesc(&activateEvent);
- return kODTrue;
- }
-
- err = AEPutParamPtr(&activateEvent, keyODActivateEventCause, typeType,
- (Ptr)&eventID, sizeof(eventID));
- if (err != noErr)
- {
- AEDisposeDesc(&activateEvent);
- return kODTrue;
- }
-
- if ( refnumForResFork )
- {
- err = AEPutParamPtr( &activateEvent, keyODRefnumFromResource,
- typeBoolean, (Ptr)&refnumForResFork,
- sizeof(refnumForResFork) );
- if (err != noErr)
- {
- AEDisposeDesc(&activateEvent);
- return kODTrue;
- }
- }
-
- // send the activate event to all OpenDoc processes
- aProcess.processInfoLength = sizeof(ProcessInfoRec);
- aProcess.processName = kODNULL;
- aProcess.processAppSpec = kODNULL;
-
- while (GetNextProcess(&psn) == noErr)
- if (GetProcessInformation(&psn, &aProcess) == noErr)
- if (aProcess.processType != 'APPL' &&
- aProcess.processSignature == kODShellSignature)
- {
- CHECKR(
- AECreateDesc(typeProcessSerialNumber, (Ptr) &psn, sizeof(psn),
- &addressDesc)
- , kODTrue);
-
- CHECKR(AEPutAttributeDesc(&activateEvent, keyAddressAttr, &addressDesc)
- , kODTrue);
- CHECKR(AESend(&activateEvent, &reply, kAENoReply, kAENormalPriority,
- kAEDefaultTimeout, kODNULL, kODNULL)
- , kODTrue);
- // this shouldn't error since the handler always returns noErr
- // ASSERT that reply == {typeNull, 0}
-
- CHECKR(AEDisposeDesc(&addressDesc), kODTrue);
- }
- err = AEDisposeDesc(&activateEvent);
- return kODTrue;
- }
-
- //------------------------------------------------------------------------------
- // VerifyAndLaunchDocumentStub
- //------------------------------------------------------------------------------
-
- OSErr VerifyAndLaunchDocumentStub(AEDesc *theDocument, AEDescList* otherParams,
- ProcessSerialNumber *psn, DescType eventID, FSSpec* seedFSSPtr,
- ODBoolean unsavedDoc)
- {
- // if the document isn't local or can't be written to, make a local stub
- // in temp items folder.
-
- FSSpec documentStub;
- FSSpec documentSpec;
- DocStubType isDuplicate;
- OSErr err;
-
- err = MakeDocumentStub(theDocument, &documentStub, &documentSpec,
- &isDuplicate, eventID, unsavedDoc);
- if (isDuplicate == kIsAlreadyLaunched)
- return err;
-
- if (!err)
- {
- if (unsavedDoc) {
- // If this doesn't work, will be tried again the next time doc is
- // launched.
- err = VerifyDocumentStub(&documentSpec, kODNULL);
- }
- err = VerifyDocumentStub(&documentStub, seedFSSPtr);
- if (!err && documentStub.name[0]!=0) {
- // need to get the alias here rather than coerce in LaunchDocument,
- // as the AEM can't coerce FSS->Alias, at least when AOCE docs are
- // involved.
- // $Opt: Remove alias stuff if unnecessary for non AOCE docs.
- AEDesc theAlias;
- OSErr aliasErr = 1; // so won't pass test below unless set
- if (isDuplicate == kIsSameAsStub)
- aliasErr = NewAliasMinimal(&documentStub,
- (AliasHandle *)&theAlias.dataHandle);
-
- if (seedFSSPtr == kODNULL ||
- seedFSSPtr->vRefNum != documentStub.vRefNum ||
- seedFSSPtr->parID != documentStub.parID ||
- seedFSSPtr->name[0] != documentStub.name[0])
- {
- if (!aliasErr) {
- theAlias.descriptorType = typeAlias;
- err= LaunchDocumentStub(theDocument, &documentStub, &theAlias,
- otherParams, psn, eventID);
- AEDisposeDesc(&theAlias);
- } else
- err= LaunchDocumentStub(theDocument, &documentStub, kODNULL,
- otherParams, psn, eventID);
- }
- }
- }
- return err;
- }
-
- //------------------------------------------------------------------------------
- // GetPrefsFileSpec
- //------------------------------------------------------------------------------
-
- OSErr GetPrefsFileSpec(ODFileSpec* prefFileSpec)
- {
- CInfoPBRec pb;
- memset (&pb,0,sizeof(pb));
-
- FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
- &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID);
- StringHandle prefsFileName = GetString( kSHLPrefsFileNameResID );
- #if ODDebug
- if ( !prefsFileName )
- DebugStr( "\pcouldn't find kSHLPrefsFileNameResID str resource" );
- #endif
- StringHandle prefsFolderName = GetString( kSHLPrefsFolderNameResID );
- //ODGetString(prefFolderName,kODPrefsFolderNameStrID);
-
- Str63 name; //must be an array because sizeof depends on it below
- //CopyPascalString(name,*prefsFolderName);
- BlockMove(*prefsFolderName,name,sizeof(name));
-
- pb.dirInfo.ioNamePtr = name;
- pb.dirInfo.ioFDirIndex = 0;
- OSErr result = PBGetCatInfoSync( &pb );
- if (result == noErr)
- {
- if( pb.hFileInfo.ioFlFndrInfo.fdFlags & kIsAlias ) {
- FSSpec spec;
- ODBoolean targetIsFolder, wasAliased;
- FSMakeFSSpec(pb.dirInfo.ioVRefNum,pb.dirInfo.ioDrParID,name, &spec);
- result = ResolveAliasFile(&spec, kODTrue, &targetIsFolder, &wasAliased);
- if (result == noErr)
- {
- if( !targetIsFolder )
- result = dirNFErr;
- // Now get dir ID of target folder:
- pb.dirInfo.ioNamePtr = spec.name;
- pb.dirInfo.ioFDirIndex = 0;
- pb.dirInfo.ioVRefNum = spec.vRefNum;
- pb.dirInfo.ioDrDirID = spec.parID;
- result = PBGetCatInfoSync( &pb );
- }
- }
-
- if (result == noErr)
- {
- FSMakeFSSpec(pb.dirInfo.ioVRefNum, pb.dirInfo.ioDrDirID, *prefsFileName, prefFileSpec);
- ReleaseResource( (Handle)prefsFileName );
- ReleaseResource( (Handle)prefsFolderName );
- }
- }
- return result;
- }
-
- //------------------------------------------------------------------------------
- // GetPrefSizeResource
- //------------------------------------------------------------------------------
-
- static ODHandle GetPrefSizeResource()
- {
- ODHandle prefSize = kODNULL;
- short theCurResFile = CurResFile();
- // Code partially copied from Prefs.cpp, should probably call a common util function
- ODFileSpec prefFileSpec;
- OSErr result = GetPrefsFileSpec(&prefFileSpec);
- if (result == noErr)
- {
- ODSShort prefResFile;
- prefResFile = FSpOpenResFile((const FSSpec *)&prefFileSpec,fsRdPerm);
-
- if (prefResFile != -1)
- {
- prefSize = Get1Resource(kSIZERsrcType, kSIZEID);
- if (prefSize)
- DetachResource(prefSize);
- CloseResFile( prefResFile );
- UseResFile(theCurResFile);
- }
- }
- return prefSize;
- }
-
- //------------------------------------------------------------------------------
- // TestAndUpdate
- //------------------------------------------------------------------------------
-
- // Check the doc's resource against the original copy.
- static OSErr TestAndUpdate(Handle origRsrc,ResType rtype,short rid)
- {
- // For SIZE-1, we need to check to see if there is an override in OpenDoc Prefs
- ODHandle prefSize = kODNULL;
- if (rtype == kSIZERsrcType && rid == kSIZEID)
- {
- prefSize = GetPrefSizeResource();
- if (prefSize != kODNULL)
- origRsrc = prefSize;
- }
-
- Handle docRsrc = Get1Resource(rtype, rid);
-
- if (docRsrc)
- {
- // Doc has resource. Compare data and possibly update:
- Size origSize = GetHandleSize(origRsrc);
- if (GetHandleSize(docRsrc)!=origSize
- || ODXmemcmp(*origRsrc,*docRsrc,origSize)!=0)
- {
- SetHandleSize(docRsrc, origSize); // Rsrc contents are different
- if (MemError()) return MemError();
- BlockMove(*origRsrc,*docRsrc,origSize); // so copy over the original data
- ChangedResource(docRsrc);
- return ResError();
- }
- else
- {
- return noErr;
- }
-
- }
- else
- {
- OSErr err= ResError();
- if (err!=noErr && err!=resNotFound)
- return err; // Something bad happened...
-
- // No such rsrc in document, so add one:
- docRsrc = origRsrc;
- err= HandToHand(&docRsrc);
- if (err) return err;
- AddResource(docRsrc,rtype,rid,nil);
- return ResError();
- }
- if (prefSize != kODNULL)
- DisposeHandle(prefSize);
- }
-
-
- //==============================================================================
- // VerifyDocument
- //==============================================================================
-
- OSErr VerifyDocumentStub(FSSpec *theStub, FSSpec* seedFSSPtr)
- {
- // VerifyDocumentStub precondition: theStub is writable or it is an OpenDoc Editor
- // All resources are verified on both 68K & PPC.
- // if the FSSpec passed in is an OpenDoc Editor
- // then we create a stationery pad seed file and
- // munge the FSSpec to point to it instead
-
- // First, grab my original copies of the rsrcs to be stuffed into the document:
- Handle origRsrc[kNumDocStubRsrcs] = { kODNULL, kODNULL, kODNULL, kODNULL };
-
- OSErr err = noErr;
- ODUShort i = 0;
- do {
- origRsrc[i] = GetResource(docStubRsrcType[i],docStubRsrcID[i]);
- } while (origRsrc[i] != kODNULL && ++i<kNumDocStubRsrcs);
-
- if (i != kNumDocStubRsrcs)
- return ResError() ? ResError() :resNotFound; // Some resource is missing
-
- // If we are opening a shared library, create a stationery seed file:
- FInfo finderInfo;
- FSpGetFInfo(theStub,&finderInfo);
- if (finderInfo.fdType == kEditorFileType)
- {
- CHECK(CreateStationerySeed(theStub, seedFSSPtr));
- }
- else if (finderInfo.fdType == kPrefFileType)
- {
- theStub->name[0] = 0;
- Str255 s;
- GetIndString(s, kODXLibsFldrStrID, 2);
- if (s[0])
- {
- ParamText(s,"\p","\p","\p");
- NoteAlert(2001,NULL);
- }
- return noErr;
- }
- else if (finderInfo.fdType == 'APPL')
- {
- theStub->name[0] = 0;
- }
-
-
- if (theStub->name[0] == 0) // File was non-Editor shared library, or unable to create stub
- return noErr;
-
- // Now open (or create) the document's resource fork:
- short theCurResFile = CurResFile();
- short docRefNum = FSpOpenResFile(theStub,fsRdWrPerm);
- if ((err = ResError()) != noErr)
- {
- // Need to create resource fork if there is none:
- if (err == eofErr)
- {
- // If other than eofErr, something's wrong
- // would have expected fnfErr.
- // if the create fails, we might try settting the eof to 0.
- // and trying the create again
- FSpCreateResFile(theStub,finderInfo.fdCreator,finderInfo.fdType,smSystemScript);
- if ((err = ResError()) == noErr)
- {
- docRefNum = FSpOpenResFile(theStub,fsRdWrPerm);
- err = ResError();
- }
- }
- if (err != noErr)
- return err;
- }
-
- // Finally, verify, add, and/or update the document resources:
- for (i = 0; i<kNumDocStubRsrcs && err==noErr; ++i)
- {
- err = TestAndUpdate(origRsrc[i],copiedRsrcType[i],copiedRsrcID[i]);
- }
-
- // Clean up our toys and go home:
- CloseResFile(docRefNum);
- if (!err)
- err= ResError();
-
- UseResFile(theCurResFile);
-
- return err;
- }
-
-
- //==============================================================================
- // CreateStationerySeed
- //==============================================================================
-
- static OSErr CreateStationerySeed(FSSpec *theDocument, FSSpec* seedFSSPtr)
- {
- // note that coming in, theDocument is actually the Editor library;
- // going out, theDocument is the newly created Stationery Seed
- // seedFSSPtr is used if already set (name[0]≠0), else it is filled in.
- // IF seedFSSPtr is NOT filled in, then theDocument name is set to null.
-
- OSErr err = noErr;
- ODEditor editorID = kODNULL;
- EditorUserStringList* editorUsrStrgPairs = kODNULL;
- ODUShort editorCount = 0;
- EditorUserStringList* pair = kODNULL;
-
- // First, read in the editorUserString NMAP from the Editor library
- short saveResFile = CurResFile();
- short resRefNum = FSpOpenResFile(theDocument,fsRdPerm);
- if ((err = ResError()) != noErr)
- return err;
-
- err = GetEditorUserStringPairs(resRefNum, &editorUsrStrgPairs, &editorCount);
- CloseResFile(resRefNum);
- UseResFile(saveResFile);
- if (err != noErr)
- return err;
-
- if (editorCount == 0)
- {
- theDocument->name[0] = 0;
- return noErr;
- }
-
- // Loop through the list of editor/editorUserString pairs
- // (libraries may contain more than one editor)
-
- for (pair = editorUsrStrgPairs;
- pair;
- pair = pair->next)
- {
- long length = pair->editor[0];
- Handle editor = NewHandleClear(1+length);
- if (MemError())
- return MemError();
- HLock(editor);
- BlockMove((Ptr)&pair->editor[1], (Ptr)*editor, length);
- HUnlock(editor);
- Str255 editorName;
- editorName[0] = pair->name.theText[0];
- BlockMove((Ptr)&pair->name.theText[1], (Ptr)&editorName[1], editorName[0]);
-
- if (seedFSSPtr != kODNULL && seedFSSPtr->name[0] != 0)
- {
- *theDocument = *seedFSSPtr;
- }
- else
- {
- // Create the stationery seed. Note: this file is NOT user visible!
- // I.e. Don't have a cow about the hard coded string.
- CreateUniqueTmpFolderForFile(theDocument, "\pStationery Seed");
- FSpCreateResFile(theDocument,kODShellSignature,kODShellSignature,smSystemScript);
- CHECK(ResError());
- if (seedFSSPtr != kODNULL)
- *seedFSSPtr = *theDocument;
- }
-
- // Plant the 'seed' resource
- saveResFile = CurResFile();
- ODSShort seedRefNum;
- seedRefNum = FSpOpenResFile(theDocument,fsRdWrPerm);
- CHECK(ResError());
-
- AddResource(editor, kDocSeedResType, Unique1ID(kDocSeedResType), editorName);
- err= ResError();
- CloseResFile(resRefNum);
- UseResFile(saveResFile);
- }
-
- for (pair = editorUsrStrgPairs;
- pair;)
- {
- EditorUserStringList* nextPair = pair->next;
- DisposePtr( (Ptr)pair );
- pair = nextPair;
- }
- return err;
- }
-
- //==============================================================================
- // string stuff
- //==============================================================================
-
- static char ODXmemcmp(char* buffer1,char* buffer2,unsigned int len)
- {
- while (len-- > 0)
- if (*buffer1++ != *buffer2++)
- return (*--buffer1)-(*--buffer2);
- return 0;
- }
-
- static size_t ODXstrlen(const char *s)
- {
- size_t len = 0;
- while (*s++) ++len;
- return len;
- }
-
- static char* ODXstrncpy(char* destStr, char* srcStr, size_t n)
- {
- char* ret = destStr;
- while (n-- > 0)
- if ((*destStr++ = *srcStr++) == 0)
- {
- while (n-- > 0)
- *destStr++ = '\0';
-
- break;
- }
-
- return ret;
- }
-
- static char* ODXstrncat(char* destStr, char* srcStr, size_t n)
- {
- size_t len = ODXstrlen(destStr);
- destStr += len;
- return ODXstrncpy(destStr, srcStr, n);
- }
-
-
- //==============================================================================
- // Launching the document process
- //==============================================================================
-
- //==============================================================================
- // LaunchDocumentStub
- //==============================================================================
-
- OSErr LaunchDocumentStub(AEDesc* theDocument, FSSpec *documentStub,
- AEDesc* theAlias, AEDescList* otherParams, ProcessSerialNumber *psn,
- DescType eventID)
- {
-
- ODUnused(otherParams);
-
- LaunchParamBlockRec launchPB;
- OSErr err;
-
- launchPB.launchBlockID = extendedBlock;
- launchPB.launchEPBLength = extendedBlockLen;
- launchPB.launchControlFlags = launchContinue | launchNoFileFlags;
- launchPB.launchAppSpec = documentStub;
-
- AEDesc launchDesc;
- AEDescList theList;
- AppleEvent theEvent;
- AEDesc myAddress;
- myAddress.descriptorType = nil;
- myAddress.dataHandle = nil;
-
- CHECK(AECreateAppleEvent(kCoreEventClass, eventID, &myAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &theEvent));
- // if (otherParams)
- // CHECK(AEPutParamDesc(&theEvent, kKeySpecialParams, otherParams));
-
- CHECK(AECreateList(nil,0,false,&theList));
- if (theAlias)
- CHECK(AEPutDesc(&theList, 0, theAlias));
- else
- CHECK(AEPutDesc(&theList, 0, theDocument));
- CHECK(AEPutParamDesc(&theEvent, keyDirectObject, &theList));
-
- CHECK(AECoerceDesc(&theEvent, typeAppParameters, &launchDesc));
- /*
- This may look a little weird, since we're actually moving the event out of the
- AppParameters descriptor. But it's necessary, the coercison to typeAppParameters
- takes the 'aevt' and puts it all in one handle, instead of
- leaving it as a AEDesc. So, only one handle is being added to
- the launch parameter block instead of an AEDesc.
- */
- HLock(launchDesc.dataHandle);
- launchPB.launchAppParameters = (AppParametersPtr)*(launchDesc.dataHandle);
-
- #if defined(powerc) || defined(__powerc)
- #else
- FlushInstructionCache();
- FlushDataCache();
- #endif
-
- err= LaunchApplication(&launchPB);
-
- if (psn)
- *psn = launchPB.launchProcessSN;
-
- return err;
- }
-
-
- void
- GetLaunchFailedParams(AppleEvent *ae, long &launchError, ProcessSerialNumber *psn,
- Str255 appName, Str255 libName)
- {
- OSErr err;
- DescType type;
- Size size;
-
- err= AEGetParamPtr(ae,keyErrorNumber,typeLongInteger,&type,
- &launchError,sizeof(launchError), &size);
- if (err)
- launchError = err;
-
- if (psn!=NULL) {
- psn->lowLongOfPSN = 0;
- psn->highLongOfPSN = 0;
- (void) AEGetParamPtr(ae,keyProcessSerialNumber,typeProcessSerialNumber,&type,
- psn,sizeof(*psn), &size);
- }
-
- err= AEGetParamPtr(ae,'APPL',typeChar,&type, &appName[1],255, &size);
- appName[0] = err ?0 :size;
-
- err= AEGetParamPtr(ae,'LIBN',typeChar,&type, &libName[1],255, &size);
- libName[0] = err ?0 :size;
- }
-
- ODBoolean myEqualPascalStrings(ConstStr255Param str1, ConstStr255Param str2)
- {
- if (str1[0] != str2[0])
- return kODFalse;
- for (int i = 1; i <= str1[0]; i++)
- {
- if (str1[i] != str2[i])
- return kODFalse;
- }
- return kODTrue;
- }
-
-
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** File: GetLocalPaths.c
- **
- ** by Jim Luther, Apple Developer Technical Support
- **
- ** Copyright © 1995 Apple Computer, Inc.
- ** All rights reserved.
- */
-
-
- pascal OSErr GetLocalPaths(FSSpec *spec,
- ForkType fork,
- unsigned long *refNumCount,
- RefNumPtr *refNums)
- {
- enum
- {
- kMaxFCBs = 348 /* The maximum number of local access paths under System 7 */
- };
-
- OSErr result;
- FCBPBRec pb;
- short index;
- Str31 tempName;
- RefNumPtr tempRefNums;
-
- /* initialize returned values */
- *refNumCount = 0;
- *refNums = NULL;
-
- /* Allocate temp storage for refNum matches */
- tempRefNums = (RefNumPtr)NewPtr(kMaxFCBs * sizeof(short));
-
- if ( tempRefNums != NULL )
- {
- /* Get FCB name in tempName */
- pb.ioNamePtr = tempName;
-
- /* Index through the open paths on the volume specified by spec->vRefNum */
- pb.ioVRefNum = spec->vRefNum;
- index = 1;
- do
- {
- pb.ioRefNum = 0;
- pb.ioFCBIndx = index;
- result = PBGetFCBInfoSync(&pb);
- if ( result == noErr )
- {
- /*
- ** See if parent directory ID matches and
- ** file name matches and
- ** the file fork (resource or data) matches
- */
- if ( (pb.ioFCBParID == spec->parID) &&
- EqualString(spec->name, tempName, false, true) &&
- ((fork == kResourceFork) == ((pb.ioFCBFlags & (1 << 9)) != 0)) )
- {
- /* It's a match - add it to the array of matches */
- tempRefNums[*refNumCount] = pb.ioRefNum;
- ++(*refNumCount);
- }
- ++index; /* next FCB index */
- }
- } while ( result == noErr );
-
- /* These errors are OK - they mean we hit the end of the FCB list */
- if ( (result == rfNumErr) || (result == fnOpnErr) )
- {
- result = noErr;
- }
-
- if ( (result == noErr) && (*refNumCount != 0) )
- {
- /* Allocate memory to return refNum matches in */
- *refNums = (RefNumPtr)NewPtr(*refNumCount * sizeof(short));
- if ( *refNums != NULL )
- {
- /* Move refNums from tempRefNums to *refNums */
- BlockMoveData((Ptr)tempRefNums, (Ptr)*refNums, (*refNumCount * sizeof(short)));
- }
- else
- {
- /* Couldn't allocate memory for refNum array */
- result = memFullErr;
- }
- }
-
- /* Free up tempRefNums storage */
- DisposePtr((Ptr)tempRefNums);
- }
- else
- {
- /* Couldn't allocate temp memory */
- result = memFullErr;
- }
-
- return ( result );
- }
-
- //------------------------------------------------------------------------------
- // GetEditorUserStringPairs
- //------------------------------------------------------------------------------
-
- OSErr GetEditorUserStringPairs(ODSShort resRefNum,
- EditorUserStringList** pairs, ODUShort* editorCount)
- {
- Handle theEdtrUSnmap = kODNULL;
- *editorCount = 0;
- ODError result = noErr;
-
- if( resRefNum != -1 ) {
- ODSShort nmapCount = Count1Resources( kODNameMappings );
- if ((result = ResError()) != noErr)
- return result;
-
- for (short i=1; i<=nmapCount; i++)
- {
- // Get the Resource
- ODHandle nmap = (ODHandle)Get1IndResource(kODNameMappings, i);
- if ((result = ResError()) != noErr)
- return result;
-
- if ( nmap != nil && !result )
- {
- HLock((ODHandle) nmap);
-
- result = GetEditorSetFromNMAP(nmap, pairs, editorCount);
-
- ReleaseResource( nmap );
- }
-
- if ((*editorCount > 0) || (result != 0))
- break;
- }
- }
- return result;
- }
-
- //------------------------------------------------------------------------------
- // GetEditorSetFromNMAP
- //------------------------------------------------------------------------------
-
- OSErr GetEditorSetFromNMAP( ODHandle nmap, EditorUserStringList** pairs,
- ODUShort* editorCount )
- {
- ODISOStr nameSpaceName = kODNULL; ODVolatile(nameSpaceName);
- ODUShort nameLen;
- ODUShort editorLen;
- ODSize bufferPos=(ODSize)*nmap;
- ODSize sizeShort = sizeof(ODUShort);
- OSErr result = noErr;
-
- BlockMove((ODPtr)bufferPos, (ODPtr)&nameLen, sizeShort);
- bufferPos += sizeShort;
-
- nameSpaceName = (ODISOStr)NewPtrClear((ODSize)nameLen+1);
- if (!nameSpaceName)
- result = memFullErr;
- else
- {
- BlockMove((ODPtr)bufferPos, (ODPtr)nameSpaceName, (ODSize)nameLen);
- bufferPos += (ODSize)nameLen;
-
- if (!ODXmemcmp(nameSpaceName,kODEditorUserString,ODXstrlen(kODEditorUserString)))
- {
- BlockMove((ODPtr)bufferPos,(ODPtr)editorCount, sizeShort);
- bufferPos += sizeShort;
-
- if ( *editorCount > 0 )
- {
-
- *pairs = (EditorUserStringList*)NewPtrClear(
- sizeof(EditorUserStringList));
- if (!*pairs)
- result = memFullErr;
- else
- {
- EditorUserStringList* thisPair = *pairs;
-
- for(ODUShort i=0; i < *editorCount && thisPair; i++)
- {
- BlockMove((ODPtr)bufferPos,(ODPtr)&editorLen,sizeShort);
- bufferPos += sizeShort;
-
- thisPair->editor[0] = editorLen;
- BlockMove((ODPtr)bufferPos,(ODPtr)&thisPair->editor[1],
- (ODSize)editorLen);
- bufferPos += (ODSize)editorLen;
- bufferPos += sizeShort;
-
- // read UserString from the nmap
- BlockMove((ODPtr)bufferPos,
- (ODPtr)&thisPair->name.theScriptCode,sizeof(ScriptCode));
- bufferPos += sizeof(ScriptCode);
- BlockMove((ODPtr)bufferPos,
- (ODPtr)&thisPair->name.theLangCode,sizeof(LangCode));
- bufferPos += sizeof(LangCode);
- BlockMove((ODPtr)bufferPos,(ODPtr)&nameLen,sizeShort);
- bufferPos += sizeShort;
- thisPair->name.theText[0] = nameLen;
- BlockMove((ODPtr)bufferPos,(ODPtr)&thisPair->name.theText[1], nameLen);
- bufferPos += nameLen;
-
- if (i+1 < *editorCount )
- {
- thisPair->next = (EditorUserStringList*)NewPtrClear(
- sizeof(EditorUserStringList));
- thisPair = thisPair->next;
- if (!thisPair)
- result = memFullErr;
-
- }
- }
- }
- }
- }
- }
-
- DisposePtr(nameSpaceName);
- return result;
- }
-
- //------------------------------------------------------------------------------
- // MoveToTrash -- $$$$$ duplicated from Prefs.cpp
- //------------------------------------------------------------------------------
- static void
- MoveToTrash( short vRefnum, long dirID, Str255 name )
- {
- short foundVRefNum;
- long foundDirID;
-
- if(!FindFolder(vRefnum, kTrashFolderType, kDontCreateFolder,
- &foundVRefNum, &foundDirID))
- {
-
- CMovePBRec paramBlock ;
- memset( ¶mBlock, 0, sizeof(paramBlock) );
-
- paramBlock.ioNamePtr = name ;
- paramBlock.ioVRefNum = foundVRefNum ;
- paramBlock.ioNewDirID = foundDirID ;
- paramBlock.ioDirID = dirID ;
-
- (void) HDelete(foundVRefNum,foundDirID,name); // ignore error (may not exist)
- OSErr result = PBCatMoveSync( ¶mBlock );
- if (result)
- (void) HDelete(vRefnum,dirID,name);
- }
- else
- (void) HDelete(vRefnum,dirID,name);
- }
-
-
- //------------------------------------------------------------------------------
- // ShowAboutScreen
- //------------------------------------------------------------------------------
-
- static short GetMainDeviceDepth( ODBoolean *isColor )
- {
- GDHandle device;
- short depth;
- PixMapHandle pmap;
-
- depth = 1;
- *isColor = kODTrue;
- device = GetMainDevice();
- if (
- (TestDeviceAttribute(device, screenDevice)) &&
- (TestDeviceAttribute(device, screenActive))
- ) {
- pmap = (*device)->gdPMap;
- depth = (*pmap)->pixelSize;
- *isColor = TestDeviceAttribute(device,gdDevType);
- }
-
- return(depth);
- }
-
- const short kSplashDlogID = kODSplashDlogID;
- const short kSplashDefaultPICTID = 131;
- const short kSplashBWPICTID = 132;
- const short kSplash16GrayPICTID = 133;
- const short kSplashBestPICTID = 134;
-
-
- DialogPtr ShowAboutScreen( )
- {
- DialogPtr aboutScreen = NULL;
- Boolean color;
- short depth = GetMainDeviceDepth(&color);
-
- short pictID = kSplashDefaultPICTID;
-
- Str255 s255; s255[0]=0;
- WindowPtr ww = FrontWindow();
- if (ww)
- GetWTitle(ww, s255);
- else
- BlockMove(LMGetCurApName(), s255, 32);
-
- if (!EqualString(s255, "\pAbout OpenDoc...", TRUE, FALSE))
- // Note, the above string is NEVER user visible, so there is no need
- // to worry about localizing it.
- if( !color && depth>=4 )
- pictID = kSplash16GrayPICTID; // Use grayscale
- else if( depth>=8 )
- pictID = kSplashBestPICTID; // Use 8-bit color
- else
- pictID = kSplashBWPICTID; // Use black-and-white
-
- if( Get1Resource('DLOG',kSplashDlogID) )
- aboutScreen = GetNewDialog(kSplashDlogID,NULL,(WindowPtr)-1L);
- if( aboutScreen ) {
- short itemHit;
- Handle scratchHandle = kODNULL;
- Rect itemRect;
-
- GetDialogItem(aboutScreen, 1, &itemHit, &scratchHandle, &itemRect);
-
- PicHandle pictHandle = (PicHandle)Get1Resource('PICT', pictID);
-
- TEHandle te = ((DialogPeek)aboutScreen)->textH;
- (**te).just = teJustCenter;
-
- struct VersRsrc {
- long versJunk;
- short region;
- Str255 versionStr;
- };
- VersRsrc **vers = (VersRsrc**) Get1Resource('vers',2);
- if( vers ) {
- HLock((Handle)vers);
- ParamText((**vers).versionStr,NULL,NULL,NULL);
- ReleaseResource((Handle)vers);
- } else
- ParamText("\p????",NULL,NULL,NULL);
-
- ShowWindow(aboutScreen);
- SelectWindow(aboutScreen);
- DrawDialog(aboutScreen);
- SetPort(aboutScreen);
- if (pictHandle)
- {
- HLock((Handle)pictHandle);
- DrawPicture(pictHandle, &itemRect);
- HUnlock((Handle)pictHandle);
- ReleaseResource((Handle)pictHandle);
- }
-
- ValidRect(&aboutScreen->portRect);
- }
- return aboutScreen;
- }
-